#include <ibase.h>
#ifndef _HIDOC_H_
#define _HIDOC_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "html.h"
#include "mmtrie.h"
#include "mmtree.h"
#define  FILE_PATH_MAX          256
#define  HI_DOCBLOCK_MAX        8388608
#ifndef  HI_PACKETDOC_COUNT
#define  HI_PACKETDOC_COUNT     256
#define  HI_QX_COUNT            256
#endif
#define  HI_DOCMBLOCK_MAX       1048576
#define  HI_PACKET_MAX          2000000
#define  HI_PACKET_INCREMENT    100000
#define  HI_XINDEX_MAX          40000000
#define  HI_XINDEX_INCREMENT    100000
#define  HI_HITASK_MAX          1000
#define  HI_HITASK_INCREMENT    100
#define  HI_NODE_DOCD           0x00
#define  HI_NODE_PARSERD        0x01
#define  HI_NODE_INDEXD         0x02
#define  HI_NODE_MAX            1024
#define  HI_NAME_MAX            64
#define  HI_IP_MAX              16
#define  HI_TASKS_MAX           32
#define  HI_LINE_SIZE           1024
static char *server_type_list[] = {"DocNode", "ParserNode", "IndexNode"}; 
#define  HI_SERVERLIST_NUM      2
#define  HI_PHRASE_ENABELD      0x00
#define  HI_PHRASE_DISABLED     0x01
#define  HI_CCOMPRESS_ENABELD   0x00
#define  HI_CCOMPRESS_DISABLED  0x01
#define  HI_LEFT_LEN            4096
#define  HI_FXDOUBLE_MAX        1024
#define  HI_FXINT_MAX           1024
#define  HI_XFLOAT_MAX          1024
#define  HI_XLONG_MAX           1024
/* sync data task */
typedef struct _HITASK
{
    short status;
    short port;
    char  ip[HI_IP_MAX];
    int   nodeid;
    int   last;
    int   popid;
    int   over;
    int   nxindexs;
    int   count;
    int   mmrootid;
    int   nqueue;
    int   upid;
    int   upover;
    int   nupdates;
    int   upcount;
}HITASK;
/* data node */
typedef struct _HINODE
{
    short status;
    short type;
    int first;
    int last;
    int total;
    int limit;
    int ntasks;
    char name[HI_NAME_MAX];
    HITASK tasks[HI_TASKS_MAX];
}HINODE;
/* histate */
typedef struct _HISTATE
{
    off_t hidoc_offset;
    off_t outdoc_offset;
    int   ccompress_status;
    int   phrase_status;
    int   globalid;
    int   packettotal;
    int   xindextotal;
    int   docpopid;
    int   popid;
    int   rootid;
    int   nnodes;
    int   nidxnodes;
    HINODE nodes[HI_NODE_MAX];
}HISTATE;
/* term node */
typedef struct _TERMNODE
{
    int  termid;
    int  term_offset;
    short noffsets;
    short nroffsets;
    int offsets[IB_OFFSET_MAX];
    int roffsets[IB_OFFSET_MAX];
    int  nprevnexts;
    char prevnexts[IB_TERMS_MAX];
}TERMNODE;
/* index */
typedef struct _HINDEX
{
    HTML *html;
    void *map;
    int nterms;
    int term_text_total;
    int term_offsets_total;
    STERM terms[IB_TERMS_MAX];
    TERMNODE nodes[IB_TERMS_MAX];
    char *block;
    int nblock;
    char *data;
    int ndata;
    char *out;
    int nout;
}HINDEX;
typedef struct _IPACKET
{
    int   nodeid;
    int   count;
    int   length;
    int   prev;
    int   next;
    off_t offset;
}IPACKET;
typedef struct _XFLOAT
{
    int id;
    double val;
}XFLOAT;
typedef struct _XLONG
{
    int id;
    long val;
}XLONG;
typedef struct _FXDOUBLE
{
    int id;
    int no;
    double val;
}FXDOUBLE;
typedef struct _FXINT
{
    int id;
    int no;
    int val;
}FXINT;
typedef struct _XINDEX
{
    short  status;
    short  nodeid;
    int    prev;
    int    next;
    int    crc;
    int    slevel;
    int    category;
    int    bitxcat;
    double rank;
}XINDEX;
typedef struct _XMIO
{
    int     fd;
    void    *map;
    off_t   end;
    off_t   size;
}XMIO;
/* idoc */
typedef struct _HIDOC
{
    void    *fp;
    void    *segmentor;
    MMTRIE  *xdict;
    MMTRIE  *mmtrie;
    MMTRIE  *namemap;
    XMIO     packetio;
    XMIO     xindexio;
    MMTRIE  *map;
    HISTATE *state;
    void    *db;
    void    *update;
    void    *queue;
    void    *mqueue;
    int     histatefd;
    int     hidocfd;
    int     outdocfd;
    void    *mutex;
    void    *logger;
    int     doc_total;
    long long int size_total;
    
    int (*set_basedir)(struct _HIDOC *, char *basedir);
    int (*set_hidoc)(struct _HIDOC *, char *hidoc);
    int (*set_phrase_status)(struct _HIDOC *, int status);
    int (*set_ccompress_status)(struct _HIDOC *, int status);
    int (*set_dict)(struct _HIDOC *, char *dictfile, char *charset);
    int (*resume)(struct _HIDOC *);
    int (*genindex)(struct _HIDOC *, HINDEX *hindex, FHEADER *fheader, IFIELD *fields, int nfields, 
            char *content, int ncontent, IBDATA *block);
    int (*push_document)(struct _HIDOC *, IBDATA *block);
    int (*pop_document)(struct _HIDOC *, HINDEX *hindex, IBDATA *block);
    int (*pop_packetid)(struct _HIDOC *, int nodeid, IPACKET *packet);
    int (*read_packet)(struct _HIDOC *, int packetid, char *data, int ndata);
    int (*add_node)(struct _HIDOC *, int type, char *name, int limit);
    int (*del_node)(struct _HIDOC *, int nodeid);
    int (*set_node_limit)(struct _HIDOC *, int nodeid, int limit);
    int (*list_nodes)(struct _HIDOC *, char *out, char *end);
    int (*add_task)(struct _HIDOC *, int nodeid, char *ip, int port);
    int (*del_task)(struct _HIDOC *, int taskid);
    int (*pop_task)(struct _HIDOC *, HITASK *task);
    int (*list_tasks)(struct _HIDOC *, int nodeid, char *out, char *end);
    int (*push_task)(struct _HIDOC *, int taskid);
    int (*over_task)(struct _HIDOC *, int taskid, int packetid);
    int (*read_index)(struct _HIDOC *, int taskid, char *data, int *len, int *count);
    int (*over_index)(struct _HIDOC *, int taskid, int id);
    int (*read_upindex)(struct _HIDOC *, int taskid, char *data, int *len, int *count);
    int (*over_upindex)(struct _HIDOC *, int taskid, int upid);
    int (*set_idx_status)(struct _HIDOC *, int globalid, int status);
    int (*set_rank)(struct _HIDOC *, XFLOAT *list, int count);
    int (*set_slevel)(struct _HIDOC *, XLONG *list, int count);
    int (*set_category)(struct _HIDOC *, XLONG *list, int count);
    int (*set_bitxcat)(struct _HIDOC *, XLONG *list, int count);
    int (*set_int_fields)(struct _HIDOC *, FXINT *list, int count);
    int (*set_double_fields)(struct _HIDOC *, FXDOUBLE *list, int count);
    int (*parse_document)(struct _HIDOC *, HINDEX *hindex);
    int (*parseHTML)(struct _HIDOC *, HINDEX *hindex, char *url, int date, 
            char *content, int ncontent, IBDATA *block);
    void (*clean)(struct _HIDOC **);
}HIDOC;
/* initialize */
HIDOC *hidoc_init();
/* gen index */
int hidoc_genindex(HIDOC *hidoc, HINDEX *hindex, FHEADER *fheader, IFIELD *fields, int nfields, 
        char *content, int ncontent, IBDATA *block);
/* resync index */
int hidoc_resync(HIDOC *hidoc);
/* new hindex */
HINDEX *hindex_new();
/* clean hindex */
void hindex_clean(HINDEX *hindex);
#ifdef __cplusplus
 }
#endif
#endif
